﻿// Qt includes
#include <QApplication>
#include <QDirIterator>
#include <QDebug>
#include <QQuickView>
#include <QProcess>
#include <QTextCodec>
#include <QFontDatabase>
// CTKPluginFramework includes
#include "ctkPluginException.h"
#include "ctkPluginContext.h"
#include "ctkPluginFrameworkLauncher.h"
#include "native_app.h"
#include "PluginInterfaces.h"
#include "../mainwindow/mainwindowservice.h"
#include <QMessageBox>
#include <locale.h>


QSharedPointer<ctkPlugin> installPlugin(const QString &path, ctkPluginContext* context)
{
    QSharedPointer<ctkPlugin> installPluginPtr = nullptr;
    qInfo() << "[Install Plugin]" << path;
    try {
        QUrl location = QUrl::fromLocalFile(QFileInfo(path).absoluteFilePath());
        //QMessageBox::information(nullptr, "install plugin", location.toString());
        installPluginPtr = context->installPlugin(location);
    } catch(const ctkPluginException &e) {
        qCritical() << QString("Failed to install plugin") << e.what();
        //QMessageBox::information(nullptr, "Install Plugin", "Install Plugin Failed");
        return nullptr;
    }

    qInfo() << "Install Plugin Success!";
    return installPluginPtr;
}

bool startPlugin(QSharedPointer<ctkPlugin> plugin)
{
    try {
        plugin->start(ctkPlugin::START_TRANSIENT);
    } catch(const ctkPluginException &e) {
        qCritical() << QString("Failed to start plugin") << e.what();
        return false;
    }

    return true;
}

bool loadManagerPlugins()
{
    qInfo() <<"ctk manager plugins: " <<  QCoreApplication::applicationDirPath() + "/plugins/";
#ifdef _WIN32
    ctkPluginFrameworkLauncher::addSearchPath(QCoreApplication::applicationDirPath() + "/plugins/");
#else
    ctkPluginFrameworkLauncher::addSearchPath(QCoreApplication::applicationDirPath() + "/../Frameworks/");
#endif
    if (ctkPluginFrameworkLauncher::start("org.commontk.eventadmin")) {
        qInfo() << "Load plugin org.commontk.eventadmin success.";
        return true;
    }

    qWarning() << "Load plugin org.commontk.eventadmin failed.";
    return false;
}

bool loadPlugins(const QString& pluginName)
{
#ifdef _WIN32
    QString pluginsPath = QCoreApplication::applicationDirPath() + "/plugins/";
#else
    QString pluginsPath = QCoreApplication::applicationDirPath() + "/../Frameworks/plugins/";
#endif
    ctkPluginContext *context = ctkPluginFrameworkLauncher::getPluginContext();

    // Install plugins
    QString installPath = pluginsPath + pluginName;
    QSharedPointer<ctkPlugin> installPluginPtr = installPlugin(installPath, context);
    if (installPluginPtr == nullptr)
        return false;

    // Start plugins
    if (!startPlugin(installPluginPtr))
        return false;
    return true;
}

int main(int argc, char *argv[])
{
#ifdef Q_OS_WIN
    setlocale(LC_ALL, ".UTF8");
#endif

#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#    if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
    QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
#    endif
#endif

    ActiveApp app(argc, argv);
    app.argvParse(argc, argv);
    app.setWindowIcon(QIcon(":/image_icon/assets/image_icon/app.png"));
    QDir::setCurrent(qApp->applicationDirPath());

    // 加载管理插件
    loadManagerPlugins();
    // 加载各个模块插件
    loadPlugins(HELLOWORD_DLL);
    loadPlugins(MAINWINDOW_DLL);

    // mainWindow
    ctkPluginContext *context = ctkPluginFrameworkLauncher::getPluginContext();
    ctkServiceReference ref = context->getServiceReference<MainWindowService>();
    if (ref) {
        MainWindowService* mainWindow = context->getService<MainWindowService>(ref);
        if (mainWindow != nullptr) {
            mainWindow->startAppWithArgs(app.getFileList());
            context->ungetService(ref);
        }
    } else {
        qFatal("No Main Window found.");
    }

    int ret = app.exec();
    return ret;
}



